/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 attackable_object.h

	$Header: /heroes4/attackable_object.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( ATTACKABLE_OBJECT_H_INCLUDED )
#define ATTACKABLE_OBJECT_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "abstract_combat_object.h"
#include "abstract_target.h"
#include "attack_angle.h"
#include "combat_action_message.h"
#include "combat_object_base.h"
#include "combat_object_list.h"
#include "creature_ability.h"
#include "has_defense.h"
#include "spell.h"

class t_combat_creature;
enum  t_creature_ability;


// ----------------------------------------------------------------------
// object which can be attacked
// ----------------------------------------------------------------------
class t_attackable_object : public virtual t_abstract_target, public virtual t_has_defense
{
public:
	t_attackable_object();

	virtual int					add_damage( int amount, t_combat_creature* source,
		                                    bool check_luck, bool permanent,
											t_combat_action_message const & damage_message );
	virtual void                add_poison( int amount, t_combat_creature const& source );
	virtual void				apply_damage( t_battlefield& battlefield, bool show_death ) = 0;
	virtual bool				begin_panic( t_combat_creature const& attacker );
	virtual bool				can_retaliate( t_combat_creature const& attacker, 
											   bool ranged, int turns = 1 ) const;
	virtual void				check_blocking();
	virtual bool				check_guardian_robe();
	virtual void				flinch( t_combat_creature const& attacker, t_combat_action_message const & message );
	t_attack_angle_list const&	get_attack_angles( t_battlefield const& battlefield );
	virtual t_abstract_combat_object const*	get_const_object() const = 0;
	virtual std::string						get_object_name() const = 0;
	virtual t_combat_object_list			get_objects() const = 0;
	int										get_new_damage() const;
	t_combat_action_message const &			get_new_damage_message() const;
	t_abstract_combat_object*				get_object();
	t_abstract_combat_object const*			get_object() const;
	virtual int								get_total_hits(bool include_guardian_angel = false, 
														   t_spell ignore_effect = k_spell_none) const = 0;
	virtual bool				has_ability( t_creature_ability ability ) const;
	virtual bool				is_alive() const = 0;
	bool						is_awake() const;
	virtual bool				is_blocking_attack() const;
	virtual bool				is_gate() const;
	virtual bool				is_giant() const;
	bool						is_in_tower() const;
	bool                        is_living_creature() const;
	void						on_battlefield_destruction_attackable_object();
	virtual void				preload_flinch( t_combat_creature const& attacker );
protected:
	bool					m_in_tower;
	int						m_new_damage;
	t_combat_action_message	m_new_damage_message;
};

inline t_attackable_object::t_attackable_object()
{
	m_in_tower = false;
	m_new_damage = 0;
}

inline t_abstract_combat_object* t_attackable_object::get_object() 
{
	return const_cast<t_abstract_combat_object*>(get_const_object());
}

inline t_abstract_combat_object const* t_attackable_object::get_object() const
{
	return get_const_object();
}

inline int t_attackable_object::get_new_damage() const
{
	return m_new_damage;
}

inline t_combat_action_message const & t_attackable_object::get_new_damage_message() const
{
	return m_new_damage_message;
}

inline bool t_attackable_object::is_in_tower() const
{
	return m_in_tower;
}

inline bool t_attackable_object::is_living_creature() const
{
	return  !has_ability( k_ability_undead ) && !has_ability( k_ability_mechanical )
		 && !has_ability( k_ability_elemental );
}


#endif // ATTACKABLE_OBJECT_H_INCLUDED